#include <stdlib.h>
#include <string.h>
#include "proc.h"
#include "co_rt.h"

Sched sched_g;
Co* c0;

void coro_init(void) {
    Sched sched_g = {NULL, 0};
}

void newproc(char* fn, char* arg0, int arg_size) {
    Co* new_co = (Co*)(malloc(sizeof(Co)));              // init new_co's params
    new_co->status = RUNABLE;
    new_co->next = NULL;
    new_co->stack_base = (char*)new_co - 1;

    char* stk = malloc(STACK_SIZE);             // malloc space to coroutine
    char* sp = stk + STACK_SIZE;
    sp -= arg_size;
    if (arg_size != 0)
        memcpy(sp, arg0, arg_size);             // copy args to stack
    sp -= 8;                                    // cal sp_reg value

    new_co->context.sp = sp;
    new_co->context.bp = sp;
    new_co->context.pc = fn;

    if (sched_g.co_head == NULL) {
        sched_g.co_head = new_co;
        sched_g.co_tail = new_co;
    } else {
        sched_g.co_tail->next = new_co;
        sched_g.co_tail = new_co;
    }
    sched_g.co_count++;
}

Co* get_freeg(void) {

}

void scheduler(void) {
    int ret = save_co(&sched_g.co_head->context);
    if (ret == 0) {
        Co* now_co = sched_g.co_head;
        Co* next_co = now_co->next;
        sched_g.co_head = next_co;
        sched_g.co_tail->next = now_co;
        sched_g.co_tail = now_co;
        goto_co(&next_co->context);      // goto next coroutine
    }
    // goto_co(&now_co->context);
}